package com.zhihuishu.micro.course.openapi.course.impl;

import com.zhihuishu.micro.course.dto.CourseDataDto;
import com.zhihuishu.micro.course.openapi.course.CCDataOpenService;
import com.zhihuishu.micro.course.openapi.course.dto.CCDataDto;
import com.zhihuishu.micro.course.openapi.course.dto.CCDataFolderMapDto;
import com.zhihuishu.micro.course.openapi.course.dto.CCDataMovieDto;
import com.zhihuishu.micro.course.service.CCDataTreenityDBService;
import com.zhihuishu.micro.course.service.CCDataTreenityService;
import com.zhihuishu.micro.course.service.CCFolderTreenityService;
import com.zhihuishu.remote.ErrorCode;
import com.zhihuishu.remote.RemoteException;
import com.zhihuishu.remote.RemoteResult;
import com.zhihuishu.toolkit.helper.BeanHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Jiangli
 * @date 2016/10/17 15:27
 */
@Service("ccDataOpenService")
public class CCDataOpenServiceImpl extends BaseOpenImpl implements CCDataOpenService {
    private static final String moduleNameCN = "cc文件";
    @Resource
    private CCDataTreenityService ccDataTreenityService;

    @Resource
    private CCDataTreenityDBService ccDataTreenityServiceDB;

    @Resource
    private CCFolderTreenityService ccFolderTreenityService;

    @Override
    public RemoteResult<List<CCDataMovieDto>> listMovieData(long courseId) throws RemoteException {
        RemoteResult<List<CCDataMovieDto>> result=new RemoteResult<List<CCDataMovieDto>>();
        try {
            //可能cache 可能db
            List<Integer> folderIds = ccFolderTreenityService.listDtoIds(courseId);
            List<Long> l_folderIds = new ArrayList<Long>(folderIds.size());
            for (Integer folderId : folderIds) {
                l_folderIds.add(folderId.longValue());
            }

            //db
            List<CourseDataDto> serviceList = ccDataTreenityService.listByFolderIdsFilterDataType(l_folderIds,"3");


            List<CCDataMovieDto> openDtoList =  new ArrayList<CCDataMovieDto>(serviceList.size());

            //convert
            for(CourseDataDto course : serviceList){
                CCDataMovieDto one = new CCDataMovieDto();
                one.setId(course.getId());
                one.setVideoId(course.getInterfaceDataId());
                one.setFileId(course.getInterfaceDataId());
                one.setSuffix(course.getSuffix());
                one.setSize(course.getSize());
                one.setFilePath(course.getUrl());
                one.setFileUrl(null);
                one.setThumbnailUrl(course.getThumbnailUrl());
                one.setVideoSize(course.getVideoSize());

                String courseName = course.getName();
                one.setFileName(courseName);

                if (course.getSize() != null) {
                    SizeUnit parse = parse(course.getSize());
                    one.setReadableSize(parse.size);
                    one.setReadableUnit(parse.unit);
                }

                openDtoList.add(one);
            }

            result.setResult(openDtoList);
        } catch (Exception e) {
            result.setSuccess(false);
            log.error(e.getMessage(),e);
            throw new RemoteException(e).setMessage("查询-" + moduleNameCN + "-视频列表-出错!") ;
        }
        return result;
    }

    class SizeUnit{
        String size;
        String unit;
    }

    public String[] unitStr = new String[]{"b","Kb","Mb","Gb"};

    public SizeUnit parse(long bytes) {
        SizeUnit ret = new SizeUnit();

        double c = bytes;

        for (int i = 0; i < unitStr.length; i++) {
            if (c/1024<1 || i==unitStr.length-1) {
                ret.unit = unitStr[i];
                BigDecimal bigDecimal = new BigDecimal(c).setScale(1, BigDecimal.ROUND_UP);
                BigDecimal floatPart = bigDecimal.subtract(new BigDecimal(bigDecimal.intValue()));

                if(floatPart.doubleValue() > 0){
                    ret.size = bigDecimal.toString();
                } else {
                    ret.size = bigDecimal.setScale(0, BigDecimal.ROUND_DOWN).toString();
                }

                return ret;
            }

            c/=1024;
        }

        return ret;
    }

    @Override
    public RemoteResult<CCDataFolderMapDto> queryMapByFolderId(List<Long> folderId) throws RemoteException {
        RemoteResult<CCDataFolderMapDto> result=new RemoteResult<CCDataFolderMapDto>();
        CCDataFolderMapDto cdfm = new CCDataFolderMapDto();
        result.setResult(cdfm);

        Map<Long,List<CCDataDto>> files = new HashMap<Long,List<CCDataDto>>();
        cdfm.setFiles(files);

        for (Long eachFid : folderId) {
            files.put(eachFid, new LinkedList<CCDataDto>());
        }

        try {
//            此处会查缓存，但视频转码后的信息在缓存中没回写，所以第二部查dto需要直接查库
//            调用过程
//              1.BaseTreenityBatchServiceImpl.listDtoIdsByMultiOneToManyKey(查缓存)
//              2.BaseTreenityBatchServiceImpl.list(查缓存)
//            List<CourseDataDto> serviceList = ccDataTreenityService.listByMultiOneToManyKey(folderId);


//            改为
//            调用过程
//              1.BaseTreenityBatchServiceImpl.listDtoIdsByMultiOneToManyKey(查缓存)
//              2.db.list(直接查库)
            List<Integer> dtoIdList = ccDataTreenityService.listDtoIdsByMultiOneToManyKey(folderId);
            List<CourseDataDto> serviceList = ccDataTreenityServiceDB.list(dtoIdList);
            //排序

            if (!CollectionUtils.isEmpty(serviceList)){
                for(CourseDataDto course : serviceList){
                    CCDataDto one = BeanHelper.transTo(course, CCDataDto.class);
                    Long curFolderId = one.getFolderId();

                    if (curFolderId != null) {
                        List<CCDataDto> l_childrenFiles = files.get(curFolderId);
                        if (l_childrenFiles == null) {
                            l_childrenFiles = new LinkedList<CCDataDto>();
                            files.put(curFolderId, l_childrenFiles);
                        }
                        l_childrenFiles.add(one);
                    }

                }
            }

        } catch (Exception e) {
            result.setSuccess(false);
            throw new RemoteException(e).setMessage("查询-" + moduleNameCN + "列表-出错!") ;
        }
        return result;
    }

    @Override
    public RemoteResult<Void> updateByDto(CCDataDto chapter, long updateUserId) throws RemoteException {
        RemoteResult<Void> result = new RemoteResult<Void>();
        if (chapter == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            CourseDataDto chapterDto = BeanHelper.transTo(chapter, CourseDataDto.class);
            ccDataTreenityService.update(chapterDto, updateUserId);

            result.setSuccess(true);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("修改-" + moduleNameCN + "-出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<CCDataDto> updateAndGetByDto(CCDataDto chapter, long updateUserId) throws RemoteException {
        RemoteResult<CCDataDto> result = new RemoteResult<CCDataDto>();
        if (chapter == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            CourseDataDto chapterDto = BeanHelper.transTo(chapter, CourseDataDto.class);
            CourseDataDto ret = ccDataTreenityService.updateAndGet(chapterDto, updateUserId);

            result.setResult(BeanHelper.transTo(ret,CCDataDto.class));
            result.setSuccess(true);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("修改-" + moduleNameCN + "-出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<List<CCDataDto>> updateByDtoList(List<CCDataDto> dtoList, long updateUserId) throws RemoteException {
        RemoteResult<List<CCDataDto>> result = new RemoteResult<List<CCDataDto>>();
        if (dtoList == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            List<CourseDataDto> list = new ArrayList<CourseDataDto>(dtoList.size());
            for (CCDataDto ccDataDto : dtoList) {
                list.add(BeanHelper.transTo(ccDataDto, CourseDataDto.class));
            }

            //只更新所处文件夹 必须先更新父文件夹id
            ccDataTreenityService.updateMulti(list, updateUserId);


            List<CCDataDto> ret = new ArrayList<CCDataDto>(dtoList.size());

            //需要在目标文件夹中判断是否重名
            for (CCDataDto one : dtoList) {
                CourseDataDto newOne = ccDataTreenityService.refreshUniqueName(BeanHelper.transTo(one, CourseDataDto.class), updateUserId);
                ret.add(BeanHelper.transTo(newOne, CCDataDto.class));
            }

            result.setResult(ret);
            result.setSuccess(true);
        } catch (Exception e) {
            throw new RemoteException(e).setMessage("修改-" + moduleNameCN + "-出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<Void> deleteByIds(List<Integer> dtoIds, long deleteUserId) throws RemoteException {
        RemoteResult<Void> result = new RemoteResult<Void>();
        if (dtoIds == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            ccDataTreenityService.deleteMulti(dtoIds, deleteUserId);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RemoteException(e).setMessage("删除-" + moduleNameCN + "-出错!");
        }
        return result;
    }
    @Override
    public RemoteResult<Void> deleteById(Integer chapterId, long deleteUserId) throws RemoteException {
        RemoteResult<Void> result = new RemoteResult<Void>();
        if (chapterId == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.ARGUMENTS_ILLEGALITY);
            return result;
        }
        try {
            ccDataTreenityService.delete(chapterId, deleteUserId);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RemoteException(e).setMessage("删除-" + moduleNameCN + "-出错!");
        }
        return result;
    }

    @Override
    public RemoteResult<List<CCDataDto>> queryListByFolderId(long folderId) throws RemoteException {
        RemoteResult<List<CCDataDto>> result=new RemoteResult<List<CCDataDto>>();
        try {
            List<CourseDataDto> serviceList = ccDataTreenityService.list(folderId);
            List<CCDataDto> openDtoList =  new ArrayList<CCDataDto>();
            if (!CollectionUtils.isEmpty(serviceList)){
                for(CourseDataDto course : serviceList){
                    CCDataDto courseOpenDto = BeanHelper.transTo(course, CCDataDto.class);
                    openDtoList.add(courseOpenDto);
                }
            }
            result.setResult(openDtoList);
        } catch (Exception e) {
            result.setSuccess(false);
            throw new RemoteException(e).setMessage("查询-" + moduleNameCN + "列表-出错!") ;
        }
        return result;
    }

    @Override
    public RemoteResult<CCDataDto> createByDto(CCDataDto courseChapterDto, long createUserId) throws RemoteException {
        RemoteResult<CCDataDto> result = new RemoteResult<CCDataDto>();
        try {
            CourseDataDto dbDto = BeanHelper.transTo(courseChapterDto, CourseDataDto.class);

            Integer newId = ccDataTreenityService.create(dbDto, createUserId);
            dbDto.setId(newId);

            CCDataDto resultDto = BeanHelper.transTo(dbDto, CCDataDto.class);

            result.setSuccess(true);
            result.setResult(resultDto);
        } catch (Exception e) {
            log.error("保存-" + moduleNameCN + "-报错");
            throw new RemoteException(e).setMessage("保存-" + moduleNameCN + "-报错!");
        }

        return result;
    }

}
